home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 January: Mac OS SDK / Dev.CD Jan 99 SDK1.toast / Development Kits / PC Card SDKs / PC Card Manager 2.0 SDK / Software / PC Card Sample / CardSpecific / CardSpecific.c next >
Encoding:
C/C++ Source or Header  |  1997-06-05  |  8.4 KB  |  345 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        CardSpecific.c
  3.  
  4.     Contains:    Card-dependent portion of the PC Card Sample Client
  5.                 In this case, a sample driver for the IBM OEM Ethernet PC Card.
  6.  
  7.     Written by:    Dave Falkenburg with lots of helpful code from:
  8.                     James Blair, Mark D. Rustad, and Richard W. Mincher.
  9.  
  10.     Copyright © 1995 by Apple Computer, Inc., all rights reserved.
  11.  
  12.     Change History (most recent first):
  13.  
  14.          <0>     11/28/95    DRF        first code.
  15. */
  16.  
  17.  
  18. #include "PCCardClient.h"
  19.  
  20. //    function prototypes
  21.  
  22. static    OSErr    GetEthernetHardwareAddress(PCCardClientGlobalsRec * globals,PCCardPerSocketState * socketState,UInt16 socket);
  23. static    OSErr    GetPacketMemorySize(PCCardClientGlobalsRec * /* globals */,PCCardPerSocketState * /* socketState */,UInt16 socket);
  24.  
  25.  
  26.  
  27. Boolean
  28. IsThisMyCard(PCCardClientGlobalsRec * /* globals */, UInt16 socket)
  29.     {
  30.     GetTuplePB    getTuplePB;
  31.     OSErr        err;
  32.     Boolean        result = false;
  33.     
  34.     //    Get the CISTPL_MANFID from the card’s CIS and compare it to our known IDs
  35.  
  36.     getTuplePB.socket = socket;
  37.     getTuplePB.attributes = 0;
  38.     getTuplePB.tupleOffset = 0;
  39.     getTuplePB.desiredTuple = CISTPL_MANFID;
  40.     
  41.     err = CSGetFirstTuple(&getTuplePB);
  42.     if (err == noErr)
  43.         {
  44.         getTuplePB.u.TupleDataPB.tupleDataMax = MAX_TUPLE_SIZE;
  45.         
  46.         err = CSGetTupleData(&getTuplePB);
  47.         if (err == noErr)
  48.             {
  49.             UInt16    manfID    = getTuplePB.u.TupleDataPB.tupleData.manufID.TPLMID_MANF;
  50.             UInt16    card    = getTuplePB.u.TupleDataPB.tupleData.manufID.TPLMID_CARD;
  51.  
  52.             //    If we match, set the result to true
  53.  
  54.             result = ((manfID == kMyTPLMID_MANF) && (card == kMyTPLMID_CARD));
  55.             }
  56.         }
  57.  
  58.     if (result)
  59.         IfDebugStr("\pIsThisMyCard: Card is mine");
  60.     else
  61.         IfDebugStr("\pIsThisMyCard: Not my card");
  62.  
  63.     return result;
  64.     }
  65.  
  66.  
  67. OSErr
  68. ConfigureMyCard(PCCardClientGlobalsRec * globals,PCCardPerSocketState * socketState, UInt16 socket)
  69.     {
  70.     ReqModRelWindowPB            wPB;
  71.     GetModRequestConfigInfoPB    configPB;
  72.     OSErr                        result;
  73.  
  74.     IfDebugStr("\pConfigureMyCard");
  75.  
  76.     //    Before we do anything, get our Ethernet hardware address
  77.  
  78.     result = GetEthernetHardwareAddress(globals,socketState,socket);
  79.     if (result != noErr)
  80.         {
  81.         IfDebugStr("\pGetEthernetHardwareAddress failed");
  82.         return result;
  83.         }
  84.  
  85.  
  86.     //    Get the size of our memory buffers
  87.  
  88.     result = GetPacketMemorySize(globals,socketState,socket);
  89.     if (result != noErr)
  90.         {
  91.         IfDebugStr("\pGetPacketMemorySize failed");
  92.         return result;
  93.         }
  94.  
  95.  
  96.     //    Allocate our Memory window, through which we will access our packet buffers
  97.     //        (we use a 300ns window, with a 16-bit datapath)
  98.  
  99.     wPB.clientHandle = globals->clientHandle;
  100.     wPB.socket = socket;
  101.     wPB.attributes = kCSEnableWindow | kCSMemoryWindow | kCS16BitDataPath | kCSAccessSpeedValid;
  102.     wPB.base = 0;
  103.     wPB.size = 0;
  104.     wPB.accessSpeed = (kCSExtAccSpeedMant1pt0 << 3) | kCSExtAccSpeedExp100ns;
  105.     result = CSRequestWindow(&wPB);
  106.  
  107.     if (result != noErr)
  108.         {
  109.         IfDebugStr("\pCSRequestWindow for Memory Window failed");
  110.         return result;
  111.         }
  112.  
  113.     socketState->memWindowHandle = wPB.windowHandle;
  114.     socketState->memBase = (void *) wPB.base;
  115.  
  116.  
  117.     //    Allocate our I/O window
  118.  
  119.     //    NOTE:    Unlike memory windows, the I/O window will only “work” once we’ve told the card
  120.     //            to listen to I/O cycles. Requesting an I/O window only programs the PC Card
  121.     //            controller chip to generate I/O cycles.  The PC Card itself must be activated
  122.     //            later via a call to RequestConfiguration.
  123.  
  124.     wPB.clientHandle = globals->clientHandle;
  125.     wPB.socket = socket;
  126.     wPB.attributes = kCSEnableWindow | kCSIOWindow;
  127.     wPB.base = 0;
  128.     wPB.size = 0;
  129.     result = CSRequestWindow(&wPB);
  130.     
  131.     if (result != noErr)
  132.         {
  133.         IfDebugStr("\pCSRequestWindow for I/O Window failed...");
  134.         return result;
  135.         }
  136.         
  137.     socketState->ioWindowHandle = wPB.windowHandle;
  138.     socketState->ioBase = (STNICReg *) wPB.base;
  139.  
  140.  
  141.     //    Lock-in the configuration for our PC Card by calling RequestConfiguration
  142.     //
  143.     //    This serves several purposes:
  144.     //        1)    It tells Card Services that we are taking over management of the card
  145.     //        2)    It tells the PC Card that it should start responding to I/O cycles
  146.     //        3)    Keeps the Finder from telling the user that there is no software for
  147.     //            for the card.
  148.     
  149.     //    Before we can request a configuration, be sure to get the previous configuration
  150.  
  151.     configPB.clientHandle = globals->clientHandle;
  152.     configPB.socket = socket;
  153.     result = CSGetConfigurationInfo(&configPB);
  154.  
  155.     if (result != noErr)
  156.         {
  157.         IfDebugStr("\pCSGetConfigurationInfo failed");
  158.         return result;
  159.         }
  160.  
  161.  
  162.     //    Set the new configuration via RequestConfiguration
  163.  
  164.     configPB.clientHandle = globals->clientHandle;
  165.     configPB.attributes |= kCSValidClient | kCSTurnOnInUse /* | kCSEnableIREQs */;
  166.     configPB.intType = kCSMemory_And_IO_Interface;
  167.     configPB.configBase = 0x20000;
  168.     configPB.status = 0x20;                //    I/O is 8 bit
  169.     configPB.copy = 0;
  170.     configPB.configIndex = 0x41;        //    Level Interrupts;  Configuration #1
  171.     configPB.present = kCSOptionRegisterPresent | kCSStatusRegisterPresent | kCSCopyRegisterPresent;
  172.  
  173.     result = CSRequestConfiguration(&configPB);
  174.  
  175.     if (result != noErr)
  176.         {
  177.         IfDebugStr("\pCSRequestConfiguration failed");
  178.         return result;
  179.         }
  180.  
  181.     //    With all that PC Card housekeeping out of the way, go ahead and
  182.     //    initialize our card-specific hardware
  183.  
  184.  
  185.     ///////////////////////////////
  186.     //
  187.     //    INITIALIZE HARDWARE HERE!
  188.     //
  189.     ///////////////////////////////
  190.  
  191.  
  192.     return noErr;
  193.     }
  194.  
  195.     
  196. OSErr
  197. UnconfigureMyCard(PCCardClientGlobalsRec * globals,PCCardPerSocketState * socketState, UInt16 socket)
  198.     {
  199.     ReqModRelWindowPB        wPB;
  200.     ReleaseConfigurationPB    configPB;
  201.     OSErr                    result;
  202.     
  203.     IfDebugStr("\pUnconfigureMyCard");
  204.  
  205.     configPB.clientHandle = globals->clientHandle;
  206.     configPB.socket = socket;
  207.     result = CSReleaseConfiguration(&configPB);
  208.     if (result != noErr)
  209.         {
  210.         IfDebugStr("\pCouldn't release configuration");
  211.         }
  212.     
  213.     wPB.clientHandle = globals->clientHandle;
  214.     wPB.windowHandle = socketState->ioWindowHandle;
  215.     result = CSReleaseWindow(&wPB);
  216.     if (result != noErr)
  217.         {
  218.         IfDebugStr("\pCouldn't release ioWindow");
  219.         }
  220.  
  221.     wPB.clientHandle = globals->clientHandle;
  222.     wPB.windowHandle = socketState->memWindowHandle;
  223.     result = CSReleaseWindow(&wPB);
  224.     if (result != noErr)
  225.         {
  226.         IfDebugStr("\pCouldn't release memWindow");
  227.         }
  228.  
  229.     return noErr;
  230.     }
  231.  
  232.  
  233. void
  234. MyCardInterruptHandler(PCCardClientGlobalsRec * /* globals */,PCCardPerSocketState * /* socketState */,UInt16 /* socket */)
  235.     {
  236.     
  237.     /////////////////////////////////////////
  238.     //
  239.     //    HANDLE YOUR CARD INTERRUPT HERE
  240.     //
  241.     /////////////////////////////////////////
  242.     
  243.     }
  244.  
  245.  
  246.  
  247.  
  248.  
  249. static    OSErr
  250. GetEthernetHardwareAddress(PCCardClientGlobalsRec * globals,PCCardPerSocketState * socketState,UInt16 socket)
  251.     {
  252.     ReqModRelWindowPB    wPB;
  253.     unsigned char *        p;
  254.     unsigned char        i;
  255.     OSErr                result;
  256.     
  257.     //    Before we do anything, go ahead and obtain our ethernet address by reading it
  258.     //    out of attribute memory.
  259.  
  260.     wPB.clientHandle = globals->clientHandle;
  261.     wPB.socket = socket;
  262.     wPB.attributes = kCSEnableWindow | kCSAttributeWindow;
  263.     wPB.base = 0;
  264.     wPB.size = 0;
  265.     result = CSRequestWindow(&wPB);
  266.  
  267.     if (result != noErr)
  268.         {
  269.         IfDebugStr("\pCSRequestWindow for attribute memory failed");
  270.         return result;
  271.         }
  272.     
  273.     //    For this card, the ethernet hardware address is stored at 0xFF0 bytes
  274.     //    into attrbute memory.
  275.     //
  276.     //    Remember that attribute memory only exists in EVEN addresses, and
  277.     //    that is why we skip ahead two bytes at a time.
  278.     
  279.     p = (unsigned char *)(wPB.base) + 0xFF0;
  280.     for(i=0; i < 6; i++, p+=2)
  281.         {
  282.         socketState->ethernetAddress[i] = *p;
  283.         }
  284.     
  285.     result = CSReleaseWindow(&wPB);
  286.     if (result != noErr)
  287.         {
  288.         IfDebugStr("\pCSReleaseWindow for attribute memory failed");
  289.         return result;
  290.         }
  291.     
  292.     return noErr;
  293.     }
  294.     
  295.     
  296. static    OSErr
  297. GetPacketMemorySize(PCCardClientGlobalsRec * /* globals */,PCCardPerSocketState * /* socketState */,UInt16 socket)
  298.     {
  299.     GetTuplePB    getTuplePB;
  300.     OSErr        result;
  301.     
  302.     //    Figure how much SRAM is available and what speed it is.
  303.  
  304.     getTuplePB.socket = socket;
  305.     getTuplePB.attributes = 0;
  306.     getTuplePB.tupleOffset = 0;
  307.     getTuplePB.desiredTuple = CISTPL_DEVICE;
  308.     result = CSGetFirstTuple(&getTuplePB);
  309.     if (result != noErr)
  310.         {
  311.         IfDebugStr("\pCSGetFirstTuple failed.");
  312.         return result;
  313.         }
  314.     
  315.     getTuplePB.u.TupleDataPB.tupleDataMax = MAX_TUPLE_SIZE;
  316.     result = CSGetTupleData(&getTuplePB);
  317.     if (result != noErr)
  318.         {
  319.         IfDebugStr("\pCSGetTupleData failed.");
  320.         return result;
  321.         }
  322.         
  323.     switch(getTuplePB.u.TupleDataPB.tupleData.tupleData[1])
  324.         {
  325.         case    0x0a:            //    16K SRAM buffer in common memory
  326.             IfDebugStr("\p16K card");
  327. //            gPageStart = 0x40;
  328. //            gPageStop = 0x80;
  329.             break;
  330.  
  331.         case    0x3a:            //    64K SRAM buffer in common memory
  332.             IfDebugStr("\p64K card");
  333. //            gPageStart = 0x00;
  334. //            gPageStop = 0xFF;
  335.             break;
  336.  
  337.         default:
  338.             IfDebugStr("\pUnknown SRAM configuration.");
  339.             result = kCSGeneralFailureErr;
  340.             break;
  341.         }
  342.     
  343.     return result;
  344.     }
  345.